/**
 * 
 */
package com.gopay.cashier.aspect;

import java.io.IOException;
import java.net.InetSocketAddress;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoConnector;
import org.aspectj.lang.JoinPoint;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.beans.factory.annotation.Autowired;


import com.gopay.cashier.web.command.BankPayChannelCommand;
import com.gopay.cashier.web.controller.BankPayChannelController;
import com.gopay.common.constants.logging.BusinessLogType;
import com.gopay.common.constants.logging.BussinessLogInfo;
import com.gopay.common.constants.logging.SendType;
import com.gopay.common.constants.logging.VoType;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.logging.business.BaseBusinessLog;
import com.gopay.common.domain.send.SendMessage;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.JsonUtils;
import com.gopay.common.util.RequestUtils;

/**
 * @BankRefLogAspect.java
 * @author Ryan
 * @2013-8-22 上午10:05:55 www.gopay.com.cn Inc.All rights reserved.
 */
public class BankRefLogAspect {

    private static final Logger logger = Logger.getLogger(BankRefLogAspect.class);
    private String ip;
    private int port;
   

    @Autowired(required = false)
    private HttpServletRequest request;

    @Resource(name = "nioSocketConnector")
    private IoConnector nioSocketConnector;

    public void doAfter(JoinPoint jp) {

        Object target = jp.getTarget();

        String method = jp.getSignature().getName();

        Object[] args = jp.getArgs();

        try {
            if (target instanceof BankPayChannelController) {

                // 日志传输对象
                BaseBusinessLog merLog = new BaseBusinessLog();
                // 表单验证
                // 时间(YYYYMMDHHMISSFFF)|系统号|操作行为|商户订单号|商户号|校验是否通过
                if ("execute".equals(method)) {
                    // 取第三个参数
                    BankPayChannelCommand command = (BankPayChannelCommand) args[2];
                    CpsGenMainOrder order = null;
                    if(order != null){
                        merLog.setSysId("cashier");

                        // get the fields from form
                        merLog.setBusinessType(BussinessLogInfo.getName(BusinessLogType.SEND_TO_BANK.value));

                        // 商户号
                        merLog.setCusId(order.getMerId());

                        // 商户订单
                        merLog.setOrderId(order.getGopayOrderId());

                        if (request != null) {
                            merLog.setReqIp(RequestUtils.getRemoteRealIpAddr(request));
                            merLog.setSendUri(request.getHeader("Referer"));
                        }

                        StringBuffer sb = new StringBuffer();

                        sb.append(DateUtils.getCurrDate()).append("|");

                        sb.append(merLog.getSysId()).append("|");

                        sb.append(BussinessLogInfo.getName(BusinessLogType.SEND_TO_BANK.value)).append("|");

                        sb.append(merLog.getOrderId()).append("|");

                        sb.append(merLog.getCusId()).append("|");

                        sb.append(order.getOutStlmId()).append("|");

                        // 发往银行信息
                        sb.append("orderId:").append(order.getGopayOrderId());
                        sb.append("amount:").append(order.getTotalOrderAmt());
                        sb.append("orderDate:").append(DateUtils.format(order.getGopayTxnTm()));
                        sb.append("userType:").append("");
                        sb.append("bank:").append(order.getOutStlmId()).append("|");

                        if (TxnStaCode.TXN_STA_CD_30101.value == (order.getTxnStaCd())) {

                            sb.append("通过");
                        } else {

                            sb.append("未通过");
                        }

                        merLog.setData(sb.toString());

                        sendLogMsg(merLog);
                    }
                }
            }
        } catch (Throwable e) {
            logger.error(e);
        }
    }

    private void sendLogMsg(BaseBusinessLog mlog) throws Throwable {

        String data = "";
        try {
            data = JsonUtils.toJson(mlog);
            logger.error("message : " + data);
        } catch (JsonGenerationException e1) {
            logger.error("", e1);
        } catch (JsonMappingException e1) {
            logger.error("", e1);
        } catch (IOException e1) {
            logger.error("", e1);
        }

        // 打印日志
        logger.error(data);
        SendMessage msg = SendMessage.getSendMessage();
        msg.setSendType(SendType.LOG);
        msg.setVoType(VoType.MER_BUSSINESS);
        msg.setData(data);

        ConnectFuture future = nioSocketConnector.connect(new InetSocketAddress(ip, port));
        // 同步调用
        future.awaitUninterruptibly();
        WriteFuture  writeFuture = future.getSession().write(msg.toString());
        writeFuture.awaitUninterruptibly();
        future.getSession().close(true);
    	
    }

    /**
     * @return the ip
     */
    public String getIp() {
        return ip;
    }

    /**
     * @param ip
     *            the ip to set
     */
    public void setIp(String ip) {
        this.ip = ip;
    }

    /**
     * @return the port
     */
    public int getPort() {
        return port;
    }

    /**
     * @param port
     *            the port to set
     */
    public void setPort(int port) {
        this.port = port;
    }

    /**
     * @return the request
     */
    public HttpServletRequest getRequest() {
        return request;
    }

    /**
     * @param request
     *            the request to set
     */
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    /**
     * @return the nioSocketConnector
     */
    public IoConnector getNioSocketConnector() {
        return nioSocketConnector;
    }

    /**
     * @param nioSocketConnector
     *            the nioSocketConnector to set
     */
    public void setNioSocketConnector(IoConnector nioSocketConnector) {
        this.nioSocketConnector = nioSocketConnector;
    }

}
